package com.sxpcwlkj.mobile.config;

import cn.dev33.satoken.stp.StpInterface;
import com.sxpcwlkj.common.utils.MapstructUtil;
import com.sxpcwlkj.framework.config.LoginObject;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 自定义权限加载接口实现类
 * 保证此类被 SpringBoot 扫描，完成 Sa-Token 的自定义权限验证扩展
 * @author shanpengnian
 */
@Component
@RequiredArgsConstructor
public class SaTokenStpInterfaceImpl implements StpInterface {

    private final LoginObject loginObject;
    /**
     * 返回一个账号所拥有的权限码集合
     * @param loginId：账号id
     * @param loginType：账号体系标识
     */
    @Override
    public List<String> getPermissionList(Object loginId, String loginType) {
        // 本 list 仅做模拟，实际项目中要根据具体业务逻辑来查询权限
        List<String> list = new ArrayList<>();
        list.add("art.*");
        return list;
    }
    /**
     * 返回一个账号所拥有的角色标识集合 (权限与角色可分开校验)
     */
    @Override
    public List<String> getRoleList(Object loginId, String loginType) {
        // 本 list 仅做模拟，实际项目中要根据具体业务逻辑来查询角色
        return new ArrayList<>();
    }

    // 获取：当前账号所拥有的权限集合
    //StpUtil.getPermissionList();

    // 判断：当前账号是否含有指定权限, 返回 true 或 false
    //StpUtil.hasPermission("user.add");

    // 校验：当前账号是否含有指定权限, 如果验证未通过，则抛出异常: NotPermissionException
    //StpUtil.checkPermission("user.add");

    // 校验：当前账号是否含有指定权限 [指定多个，必须全部验证通过]
    //StpUtil.checkPermissionAnd("user.add", "user.delete", "user.get");

    // 校验：当前账号是否含有指定权限 [指定多个，只要其一验证通过即可]
    //StpUtil.checkPermissionOr("user.add", "user.delete", "user.get");

    // 获取：当前账号所拥有的角色集合
    //StpUtil.getRoleList();

    // 判断：当前账号是否拥有指定角色, 返回 true 或 false
    //StpUtil.hasRole("super-admin");

    // 校验：当前账号是否含有指定角色标识, 如果验证未通过，则抛出异常: NotRoleException
    //StpUtil.checkRole("super-admin");

    // 校验：当前账号是否含有指定角色标识 [指定多个，必须全部验证通过]
    //StpUtil.checkRoleAnd("super-admin", "shop-admin");

    // 校验：当前账号是否含有指定角色标识 [指定多个，只要其一验证通过即可]
    //StpUtil.checkRoleOr("super-admin", "shop-admin");

    //StpUtil.logout(10001);                    // 强制指定账号注销下线
    //StpUtil.logout(10001, "PC");              // 强制指定账号指定端注销下线
    //StpUtil.logoutByTokenValue("token");      // 强制指定 Token 注销下线

    //StpUtil.kickout(10001);                    // 将指定账号踢下线
    //StpUtil.kickout(10001, "PC");              // 将指定账号指定端踢下线
    //StpUtil.kickoutByTokenValue("token");      // 将指定 Token 踢下线


    // 登录校验：只有登录之后才能进入该方法
    //@SaCheckLogin

    //写法一：orRole = "admin"，代表需要拥有角色 admin 。
    //写法二：orRole = {"admin", "manager", "staff"}，代表具有三个角色其一即可。
    //写法三：orRole = {"admin, manager, staff"}，代表必须同时具有三个角色。
    // 角色权限双重 “or校验”：具备指定权限或者指定角色即可通过校验
    //@SaCheckRole(value = "user.add", orRole = "admin")


    // 权限校验：必须具有指定权限才能进入该方法
    // 注解式鉴权：只要具有其中一个权限即可通过校验
    //@SaCheckPermission(value = {"user-add", "user-all", "user-delete"}, mode = SaMode.OR)


    // 二级认证校验：必须二级认证之后才能进入该方法
    // 此接口加上了 @SaIgnore 可以游客访问
    //@SaIgnore
    //@SaCheckSafe()


    // Http Basic 校验：只有通过 Basic 认证后才能进入该方法
    //@SaCheckBasic(account = "sa:123456")


    // 校验当前账号是否被封禁 comment 服务，如果已被封禁会抛出异常，无法进入方法
    //@SaCheckDisable("comment")

    // 在 `@SaCheckOr` 中可以指定多个注解，只要当前会话满足其中一个注解即可通过验证，进入方法。
    // 当前客户端只要有 [ login 账号登录] 或者 [user 账号登录] 其一，就可以通过验证进入方法。
    //@SaCheckOr(
         //   login = { @SaCheckLogin(type = "login"), @SaCheckLogin(type = "user") }
         //   role = @SaCheckRole("admin"),
         //   permission = @SaCheckPermission("user.add"),
         //   safe = @SaCheckSafe("update-password"),
         //   basic = @SaCheckBasic(account = "sa:123456"),
         //   disable = @SaCheckDisable("submit-orders")
    // )


    // 获取当前账号 id 的 Account-Session (必须是登录后才能调用)
    //StpUtil.getSession();

    // 获取当前账号 id 的 Account-Session, 并决定在 Session 尚未创建时，是否新建并返回
    //StpUtil.getSession(true);

    // 获取账号 id 为 10001 的 Account-Session
    //StpUtil.getSessionByLoginId(10001);

    // 获取账号 id 为 10001 的 Account-Session, 并决定在 Session 尚未创建时，是否新建并返回
    //StpUtil.getSessionByLoginId(10001, true);

    // 获取 SessionId 为 xxxx-xxxx 的 Account-Session, 在 Session 尚未创建时, 返回 null
    //StpUtil.getSessionBySessionId("xxxx-xxxx");

    // 获取当前 Token 的 Token-Session 对象
    //StpUtil.getTokenSession();

    // 获取指定 Token 的 Token-Session 对象
    //StpUtil.getTokenSessionByToken(token);

    // 查询指定key的Session是否存在
    //SaSessionCustomUtil.isExists("goods-10001");

    // 获取指定key的Session，如果没有，则新建并返回
    //SaSessionCustomUtil.getSessionById("goods-10001");

    // 获取指定key的Session，如果没有，第二个参数决定是否新建并返回
    //SaSessionCustomUtil.getSessionById("goods-10001", false);

    // 删除指定key的Session
    //SaSessionCustomUtil.deleteSessionById("goods-10001");

    // 写值
    //session.set("name", "zhang");

    // 写值 (只有在此key原本无值的时候才会写入)
    //session.setDefaultValue("name", "zhang");

    // 取值
    //session.get("name");

    // 取值 (指定默认值)
    //session.get("name", "<defaultValue>");

    // 取值 (若无值则执行参数方法, 之后将结果保存到此键名下,并返回此结果   若有值则直接返回, 无需执行参数方法)
    //session.get("name", () -> {
    //        return ...;
    //    });

    // ---------- 数据类型转换： ----------
    //session.getInt("age");         // 取值 (转int类型)
    //session.getLong("age");        // 取值 (转long类型)
    //session.getString("name");     // 取值 (转String类型)
    //session.getDouble("result");   // 取值 (转double类型)
    //session.getFloat("result");    // 取值 (转float类型)
    //session.getModel("key", Student.class);     // 取值 (指定转换类型)
    //session.getModel("key", Student.class, <defaultValue>);  // 取值 (指定转换类型, 并指定值为Null时返回的默认值)

    // 是否含有某个key (返回 true 或 false)
    //session.has("key");

    // 删值
    //session.delete('name');

    // 清空所有值
    //session.clear();

    // 获取此 Session 的所有key (返回Set<String>)
    //session.keys();

    // 获取当前 Token 的匿名 Token-Session （可在未登录情况下使用的 Token-Session）
    //StpUtil.getAnonTokenSession();






}

